import { validateProp } from './message.js'
import defineReactive from '../../core/defineReactive.js'
import { noop } from '../../../ather/util.js'
import observe from '../../core/observe.js'
import Watcher from '../../core/Watcher.js'

export function initProps(vm, propsOptions) {
    // 未来优化
    const propsData = vm.$options.propsData || {} //默认给{}
    const props = vm._props = {} //默认给{}
    const keys = vm.$options._propKeys = [] //默认给[]
    for (const key in propsOptions) { // 遍历props
        keys.push(key)
        const value = validateProp(key, propsOptions, propsData, vm) // 未来再写
        defineReactive(props, key, value)
            // if (!(key in vm)) { // 未来再写
            //   proxy(vm, `_props`, key)
            // }
    }
}
export function initMethods(vm, methods) {
    const props = vm.$options.props
    for (const key in methods) {
        vm[key] = typeof methods[key] !== 'function' ? noop : methods[key].bind(vm)
    }
}
export function initData(vm) {
    let data = vm.$options.data
    data = vm._data = typeof data === 'function' ?
        getData(data, vm) :
        data || {}
    const keys = Object.keys(data)
    let i = keys.length
    while (i--) {
        const key = keys[i]
        observe(data, true /* asRootData */ )
        proxy(vm, `_data`, key)
    }
}
const computedWatcherOptions = { lazy: true }
export function initComputed(vm, computed) {
    const watchers = vm._computedWatchers = Object.create(null)
    for (const key in computed) {
        const userDef = computed[key]
        const getter = typeof userDef === 'function' ? userDef : userDef.get
        watchers[key] = new Watcher(
            vm,
            getter || noop,
            noop,
            computedWatcherOptions
        )
        if (!(key in vm)) {
            defineComputed(vm, key, userDef)
        }
    }
}
export function initWatch(vm, watch) {
    for (const key in watch) {
        const hender = watch[key]

        if (Array.isArray(hender)) {
            for (let i = 0; i < handler.length; i++) {
                createWatcher(vm, key, hender[i])
            }
        } else {
            createWatcher(vm, key, hender)

        }
    }
}

function getData(data, vm) {
    return data.call(vm, vm)
}


export function proxy(target, sourceKey, key) {
    Object.defineProperty(target, key, {
        enumerable: true,
        configurable: true,
        get() {
            console.log(this)
            return this[sourceKey][key]
        },
        set(value) {
            this[sourceKey][key] = value
        }
    })
}

export function defineComputed(vm, key, userDef) {
    if (typeof userDef === 'function') {
        Object.defineProperty(vm, key, {
            enumerable: true,
            configurable: true,
            get() {
                return userDef.call(this)
            },
            set() {}
        })
    } else {
        Object.defineProperty(vm, key, {
            enumerable: true,
            configurable: true,
            get() {
                return userDef.get.call(this)
            },
            set(value) {
                userDef.set.call(this, value)
            }
        })
    }

}



function createWatcher(vm, expOrFn, handler) {
    return vm.$watch(expOrFn, handler)
}